import axios from 'axios';
import router from '@/router';
import qs from 'qs'; //qs.stringify()将对象 序列化成URL的形式，以&进行拼接
import { Message } from 'view-design';

// 环境的切换
if (process.env.NODE_ENV == 'development') {
  axios.defaults.baseURL = '/';
} else if (process.env.NODE_ENV == 'production') {
  axios.defaults.baseURL = '/';
}
// 创建axios实例
const $axios = axios.create({
  timeout: 30000, // 设置超时时间
  headers: { // post请求头
    'Content-Type': 'application/json; charset=UTF-8; application/x-www-form-urlencoded',
    'Access-Control-Allow-Headers': 'X-Requested-With',
    'Access-Control-Allow-Origin': '*',
  },
  withCredentials: true,  //设置cross跨域 并设置访问权限 允许跨域携带cookie信息
})
// Vue.prototype.$http = axios; // 并发请求

//http request 全局请求拦截器(发送请求之前)
$axios.interceptors.request.use(
  config => {
    // console.group('发送请求之前')
    // console.log(config)
    // console.groupEnd()

    // 获取localStorage中的token 或 store中的token
    const token = localStorage.getItem('userToken')?localStorage.getItem('userToken'):'';
    // const token = store.state.userToken;

    // 判断是否存在token，如果存在的话，则每个http header都加上token
    if(token && token != "undefined"){
      // config.headers.Authorization = token;  //请求头加上token
      config.headers.token = token;  //请求头加上token
      // config.headers.common['token'] = token;  //请求头加上token
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
);

//http response 全局响应拦截器(服务器返回数据之后) 即异常处理
$axios.interceptors.response.use(
  response => {
    // console.group('数据返回之后')
    // console.log(response)
    // console.groupEnd()

    const code = response.status;
    if ((code >= 200 && code < 300) || code === 304) {
      return Promise.resolve(response.data);
    } else {
      return Promise.reject(response);
    }
  },
  error => {
    if (error.response) {
      switch (error.response.status) {
        // 登录失效，清除token信息并跳转到登陆页面
        case 401:
          Message.error('会话失效，请重新登录!')
          localStorage.removeItem('userToken');
          store.commit('logOut', null);
          router.push('/login');
          break
        // 403 token过期，清除本地token和清空vuex中token对象，返回登录页
        case 403:
          Message.error('登录过期，请重新登录!')
          // 清除token
          localStorage.removeItem('userToken');
          store.commit('logOut', null);
          router.push('/login');
          break
        // 404请求不存在
        case 404:
          Message.error('未找到相关服务，请打开控制台查看详情!')
          console.error(error.response.data);
          break
        // 500网络错误
        case 500:
          Message.error('系统错误，请打开控制台查看错误详情!')
          console.error(error.response.data);
          break
        // 503网关异常
        case 503:
          Message.error('网关异常，请打开控制台查看详情!')
          console.error(error.response.data)
          break

        // 其他错误，直接抛出错误提示
        default:
          Message.error(error.response.statusText);
          console.error(error.response.statusTex)
      }
    } else {
      // 请求超时或者网络有问题
      if (error.message.includes('timeout')) {
        Message.error('请求超时！请检查网络是否正常！')
      } else {
        Message.error('请求失败，请检查网络是否已连接！')
      }
    }
    return Promise.reject(error)
  }
)


// 请求方法 - 不指定请求方式时，默认post，参数在body体内，为拼接格式
export const $ajax = (url, params = {}, options) => {
  // Object.assign：Object.assign(target, ...sources)
  // 将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象
  let _options = Object.assign({ method: 'post', withCredentials: true }, options)
  console.log(_options);
  // 新增upload方法模式 确保上传模式下post的参数不被处理
  let [_params, _data] = ['', '']
  if (_options.method === 'get') {
    [_params, _data] = [params, '']
  } else if (_options.method === 'post') {
    [_params, _data] = ['', qs.stringify(params)]
  } else if (_options.method === 'upload') {
    [_params, _data] = ['', params]
  } else if (_options.method === 'getload') {
    [_params, _data] = ['', qs.stringify(params)]
  }
  console.log(_params, _data);
  // let [_params, _data] = _options.method === 'get' ? [params, ''] : ['', qs.stringify(params)]

  return $axios({
    method: _options.method === 'get' ? 'get' : 'post',
    url: url,
    params: _params,
    data: _data,
    withCredentials: _options.withCredentials
    // contentType: _options.contentType === undefined,
    // processData: _options.processData === undefined,
    // responseType: _options.responseType === undefined,
  }).then(res => {
    let _res = res
    return _res
  }).catch(error => {
    return error
  })
}

// 请求方法 - 指定请求方式
export default {
  // get请求：参数在地址栏，以?拼接
  get(url, params) {
    if(params == null){
      return $axios.get(url,null);
    } else {
      return $axios.get(url,{params:params});
    }
  },

  // post请求: 参数在body体内，为json格式
  post(url, params) { 
    return $axios.post(url, params); 
  },

  // post请求 Content-Type：application/x-www-form-urlencoded ：表单提交
  urlencodedPost(url, params) { 
    return $axios.post(url, params, {headers:{'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}}); 
  },

  // delete请求
  delete(url, params) { 
    return $axios.delete(url, params); 
  },

  // put请求
  put(url, params) { 
    return $axios.put(url, params); 
  },


  // 封装axios的get请求
  getData(url, params) {
    return new Promise((resolve, reject) => {
      $axios.get(url, params).then(res => {
          resolve(res.data);
        })
        .catch(error => {
          reject(error);
        });
    });
  },
  // 封装axios的post请求
  postData(url, params) {
    return new Promise((resolve, reject) => {
      $axios.post(url, QS.stringify(params)).then(res => {
          resolve(res.data);
        })
        .catch(error => {
          reject(error);
        });
    });
  }
}
